package com.exercise240710.service;

import com.exercise240710.DTO.ReportStudentPhysicalDTO;
import com.exercise240710.DTO.StudentPhysicalDTO;
import com.exercise240710.entity.PhysicalTest;
import com.exercise240710.entity.StudentInfo;
import com.exercise240710.mapper.PhysicalTestMapper;
import com.exercise240710.mapper.StudentInfoMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
public class ReconfigrationService {

    private StudentInfoMapper studentInfoMapper;

    private PhysicalTestMapper physicalTestMapper;

    @Transactional
    public List<PhysicalTest> testTest(List<Long> student_ids) {
        return physicalTestMapper.selectPhysicalByStudentIds(student_ids);
    }

    @Transactional
    public StudentInfo findStudentById(Long id) {
        return studentInfoMapper.selectById(id);
    }

    @Transactional
    public StudentInfo findStudentByIdSeq(String id_seq) {
        return studentInfoMapper.selectByIdSeq(id_seq);
    }

    @Transactional
    public List<StudentInfo> findStudentByCondition(
            Long min_id, Long max_id, String id_seq,
            String name, String gender, Short min_age,
            Short max_age, String school, Integer min_student_num,
            Integer max_student_num, String subject, String phone,
            String email, String live_place, String iban,
            Integer pageSize, Long pageNum
    ) {
        return studentInfoMapper
                .selectStudentByCondition(
                        min_id, max_id, id_seq,
                        name, gender, min_age,
                        max_age, school, min_student_num,
                        max_student_num, subject, phone,
                        email, live_place, iban,
                        pageSize * (pageNum - 1), pageSize
                );
    }

    @Transactional
    public int updateStudent(String id_seq,
                             String name, String gender, Short age,
                             String school, Integer student_num, String subject,
                             String phone, String email, String live_place,
                             String iban) {
        return studentInfoMapper.updateStudent(id_seq,
                name, gender, age,
                school, student_num, subject,
                phone, email, live_place,
                iban);
    }

    @Transactional
    public int addStudent(
            String id_seq,
            String name, String gender, Short age,
            String school, Integer student_num, String subject,
            String phone, String email, String live_place,
            String iban
    ) {
        return studentInfoMapper.insertStudent(id_seq,
                name, gender, age,
                school, student_num, subject,
                phone, email, live_place,
                iban);
    }

    @Transactional
    public int deleteStudentByIdSeq(String id_seq) {
        physicalTestMapper.deletePhysicalByIdSeq(id_seq);
        return studentInfoMapper.deleteStudentByIdSeq(id_seq);
    }

    @Transactional
    public int deletePhysicalByIdSeq(String id_seq) {
        return physicalTestMapper.deletePhysicalByIdSeq(id_seq);
    }

    @Transactional
    public List<PhysicalTest> findPhysicalByCondition(
            Long min_id, Long max_id, String id_seq, Float min_height,
            Float max_height, Float min_weight, Float max_weight,
            Short min_vital_capacity, Short max_vital_capacity,
            Float min_seated_forward_bend, Float max_seated_forward_bend,
            Short min_standing_long_jump, Short max_standing_long_jump,
            Float min_rush_50, Float max_rush_50, Float min_long_distance_run,
            Float max_long_distance_run, Short min_sit_ups, Short max_sit_ups,
            String test_date, Long min_student_id, Long max_student_id,
            Integer pageSize, Long pageNum
    ) {
        return physicalTestMapper.selectPhysicalByCondition(
                min_id, max_id, id_seq, min_height,
                max_height, min_weight, max_weight,
                min_vital_capacity, max_vital_capacity,
                min_seated_forward_bend, max_seated_forward_bend,
                min_standing_long_jump, max_standing_long_jump,
                min_rush_50, max_rush_50, min_long_distance_run,
                max_long_distance_run, min_sit_ups, max_sit_ups,
                test_date, min_student_id, max_student_id,
                pageSize * (pageNum - 1), pageSize
        );
    }

    @Transactional
    public int addPhysical(
            String id_seq,
            Float height,
            Float weight,
            Short vital_capacity,
            Float seated_forward_bend,
            Short standing_long_jump,
            Float rush_50,
            Float long_distance_run,
            Short sit_ups,
            String test_date
    ) {
        StudentInfo studentInfo = findStudentByIdSeq(id_seq);
        if (studentInfo == null) {
            return 0;
        }
        return physicalTestMapper.insertPhysical(
                id_seq, height, weight, vital_capacity,
                seated_forward_bend, standing_long_jump,
                rush_50, long_distance_run, sit_ups,
                test_date, studentInfo.getId()
        );
    }

    @Transactional
    public List<StudentPhysicalDTO>
    findStudentPhysicalJoin(
            Long min_id, Long max_id, String id_seq,
            String name, String gender, Short min_age,
            Short max_age, String school, Integer min_student_num,
            Integer max_student_num, String subject, String phone,
            String email, String live_place, String iban,
            Integer pageSize, Long pageNum
    ) {
        return studentInfoMapper.findStudentPhysicalJoin(
                min_id, max_id, id_seq,
                name, gender, min_age,
                max_age, school, min_student_num,
                max_student_num, subject, phone,
                email, live_place, iban,
                pageSize * (pageNum - 1), pageSize
        );
    }

    @Transactional
    public List<ReportStudentPhysicalDTO>
    reportStudentPhysical(
            Long min_id, Long max_id, String id_seq,
            String name, String gender, Short min_age,
            Short max_age, String school, Integer min_student_num,
            Integer max_student_num, String subject, String phone,
            String email, String live_place, String iban,
            Integer pageSize, Long pageNum
    ) {
        List<StudentInfo> studentInfos = studentInfoMapper.selectStudentByCondition(
                min_id, max_id, id_seq,
                name, gender, min_age,
                max_age, school, min_student_num,
                max_student_num, subject, phone,
                email, live_place, iban,
                pageSize * (pageNum - 1), pageSize
        );

        List<Long> student_ids = new ArrayList<>();
        for (StudentInfo studentInfo : studentInfos) {
            student_ids.add(studentInfo.getId());
        }
        List<PhysicalTest> physicalTests = physicalTestMapper
                .selectPhysicalByStudentIds(student_ids);

        List<ReportStudentPhysicalDTO> res = new ArrayList<>();
        for (StudentInfo studentInfo : studentInfos) {
            List<PhysicalTest> wantedPhysicalTest = physicalTests
                    .stream().filter(
                            (PhysicalTest pt) -> pt.getStudent_id()
                                    .equals(studentInfo.getId())
                    ).toList();
            res.add(new ReportStudentPhysicalDTO(studentInfo, wantedPhysicalTest));
        }
        return res;
//        StudentInfo studentInfo = studentInfoMapper.selectByIdSeq(id_seq);
//        List<PhysicalTest> physicalTests = physicalTestMapper.selectPhysicalByStudentId(studentInfo.getId());
//        return new ReportStudentPhysicalDTO(studentInfo, physicalTests);
    }


}
